package net.siufung.boot.datasource.converts;


import net.siufung.boot.datasource.enums.ColumnTypes;
import net.siufung.boot.datasource.enums.DateTypes;
import net.siufung.boot.datasource.rules.IColumnType;
import net.siufung.boot.datasource.rules.IColumnTypeConvert;

/**
 * @author 陈建峰
 * @since 2022/8/12 3:33 下午
 */
public class MySql5TypeConvert implements IColumnTypeConvert {

    public static final MySql5TypeConvert INSTANCE = new MySql5TypeConvert();

    @Override
    public IColumnType processTypeConvert(DateTypes dateTypes, String fieldType) {
        return ColumnTypeConverts.use(fieldType)
                .test(ColumnTypeConverts.containsAny("char", "text", "json", "enum").then(ColumnTypes.STRING))
                .test(ColumnTypeConverts.contains("bigint").then(ColumnTypes.LONG))
                .test(ColumnTypeConverts.containsAny("tinyint(1)", "bit").then(ColumnTypes.BOOLEAN))
                .test(ColumnTypeConverts.contains("int").then(ColumnTypes.INTEGER))
                .test(ColumnTypeConverts.contains("decimal").then(ColumnTypes.BIG_DECIMAL))
                .test(ColumnTypeConverts.contains("clob").then(ColumnTypes.CLOB))
                .test(ColumnTypeConverts.contains("blob").then(ColumnTypes.BLOB))
                .test(ColumnTypeConverts.contains("binary").then(ColumnTypes.BYTE_ARRAY))
                .test(ColumnTypeConverts.contains("float").then(ColumnTypes.FLOAT))
                .test(ColumnTypeConverts.contains("double").then(ColumnTypes.DOUBLE))
                .test(ColumnTypeConverts.containsAny("date", "time", "year").then(t -> toDateType(dateTypes, t)))
                .or(ColumnTypes.STRING);
    }

    @Override
    public IColumnType toDateType(DateTypes dateTypes, String type) {
        switch (dateTypes) {
            case ONLY_DATE:
                return ColumnTypes.DATE;
            case SQL_PACK:
                switch (type) {
                    case "date":
                    case "year":
                        return ColumnTypes.DATE_SQL;
                    case "time":
                        return ColumnTypes.TIME;
                    default:
                        return ColumnTypes.TIMESTAMP;
                }
            case TIME_PACK:
                switch (type) {
                    case "date":
                        return ColumnTypes.LOCAL_DATE;
                    case "time":
                        return ColumnTypes.LOCAL_TIME;
                    case "year":
                        return ColumnTypes.YEAR;
                    default:
                        return ColumnTypes.LOCAL_DATE_TIME;
                }
            default:
                return ColumnTypes.STRING;
        }
    }
}
